/*
 *
 *    Copyright (c) 2022 Project CHIP Authors
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

// THIS FILE IS GENERATED BY ZAP

#include <cinttypes>
#include <cstdint>

#include <app-common/zap-generated/callback.h>
#include <app-common/zap-generated/cluster-objects.h>
#include <app-common/zap-generated/ids/Clusters.h>
#include <app-common/zap-generated/ids/Commands.h>
#include <app/CommandHandler.h>
#include <app/InteractionModelEngine.h>
#include <app/util/util.h>
#include <lib/core/CHIPSafeCasts.h>
#include <lib/support/TypeTraits.h>

namespace chip {
namespace app {

// Cluster specific command parsing

namespace Clusters {

namespace ColorControl {

Protocols::InteractionModel::Status DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath,
                                                          TLV::TLVReader & aDataTlv)
{
    CHIP_ERROR TLVError = CHIP_NO_ERROR;
    bool wasHandled     = false;
    {
        switch (aCommandPath.mCommandId)
        {
        case Commands::MoveToHue::Id: {
            Commands::MoveToHue::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfColorControlClusterMoveToHueCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::MoveHue::Id: {
            Commands::MoveHue::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfColorControlClusterMoveHueCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::StepHue::Id: {
            Commands::StepHue::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfColorControlClusterStepHueCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::MoveToSaturation::Id: {
            Commands::MoveToSaturation::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfColorControlClusterMoveToSaturationCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::MoveSaturation::Id: {
            Commands::MoveSaturation::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfColorControlClusterMoveSaturationCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::StepSaturation::Id: {
            Commands::StepSaturation::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfColorControlClusterStepSaturationCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::MoveToHueAndSaturation::Id: {
            Commands::MoveToHueAndSaturation::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfColorControlClusterMoveToHueAndSaturationCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::MoveToColor::Id: {
            Commands::MoveToColor::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfColorControlClusterMoveToColorCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::MoveColor::Id: {
            Commands::MoveColor::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfColorControlClusterMoveColorCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::StepColor::Id: {
            Commands::StepColor::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfColorControlClusterStepColorCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::MoveToColorTemperature::Id: {
            Commands::MoveToColorTemperature::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfColorControlClusterMoveToColorTemperatureCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::EnhancedMoveToHue::Id: {
            Commands::EnhancedMoveToHue::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfColorControlClusterEnhancedMoveToHueCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::EnhancedMoveHue::Id: {
            Commands::EnhancedMoveHue::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfColorControlClusterEnhancedMoveHueCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::EnhancedStepHue::Id: {
            Commands::EnhancedStepHue::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfColorControlClusterEnhancedStepHueCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::EnhancedMoveToHueAndSaturation::Id: {
            Commands::EnhancedMoveToHueAndSaturation::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled =
                    emberAfColorControlClusterEnhancedMoveToHueAndSaturationCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::ColorLoopSet::Id: {
            Commands::ColorLoopSet::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfColorControlClusterColorLoopSetCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::StopMoveStep::Id: {
            Commands::StopMoveStep::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfColorControlClusterStopMoveStepCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::MoveColorTemperature::Id: {
            Commands::MoveColorTemperature::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfColorControlClusterMoveColorTemperatureCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::StepColorTemperature::Id: {
            Commands::StepColorTemperature::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfColorControlClusterStepColorTemperatureCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        default: {
            // Unrecognized command ID, error status will apply.
            ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI,
                         ChipLogValueMEI(aCommandPath.mCommandId), ChipLogValueMEI(aCommandPath.mClusterId));
            return Protocols::InteractionModel::Status::UnsupportedCommand;
        }
        }
    }

    if (CHIP_NO_ERROR != TLVError || !wasHandled)
    {
        ChipLogProgress(Zcl, "Failed to dispatch command, TLVError=%" CHIP_ERROR_FORMAT, TLVError.Format());
        return Protocols::InteractionModel::Status::InvalidCommand;
    }

    // We use success as a marker that no special handling is required
    // This is to avoid having a std::optional which uses slightly more code.
    return Protocols::InteractionModel::Status::Success;
}

} // namespace ColorControl

namespace DishwasherAlarm {

Protocols::InteractionModel::Status DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath,
                                                          TLV::TLVReader & aDataTlv)
{
    CHIP_ERROR TLVError = CHIP_NO_ERROR;
    bool wasHandled     = false;
    {
        switch (aCommandPath.mCommandId)
        {
        case Commands::Reset::Id: {
            Commands::Reset::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfDishwasherAlarmClusterResetCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::ModifyEnabledAlarms::Id: {
            Commands::ModifyEnabledAlarms::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfDishwasherAlarmClusterModifyEnabledAlarmsCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        default: {
            // Unrecognized command ID, error status will apply.
            ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI,
                         ChipLogValueMEI(aCommandPath.mCommandId), ChipLogValueMEI(aCommandPath.mClusterId));
            return Protocols::InteractionModel::Status::UnsupportedCommand;
        }
        }
    }

    if (CHIP_NO_ERROR != TLVError || !wasHandled)
    {
        ChipLogProgress(Zcl, "Failed to dispatch command, TLVError=%" CHIP_ERROR_FORMAT, TLVError.Format());
        return Protocols::InteractionModel::Status::InvalidCommand;
    }

    // We use success as a marker that no special handling is required
    // This is to avoid having a std::optional which uses slightly more code.
    return Protocols::InteractionModel::Status::Success;
}

} // namespace DishwasherAlarm

namespace FanControl {

Protocols::InteractionModel::Status DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath,
                                                          TLV::TLVReader & aDataTlv)
{
    CHIP_ERROR TLVError = CHIP_NO_ERROR;
    bool wasHandled     = false;
    {
        switch (aCommandPath.mCommandId)
        {
        case Commands::Step::Id: {
            Commands::Step::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfFanControlClusterStepCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        default: {
            // Unrecognized command ID, error status will apply.
            ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI,
                         ChipLogValueMEI(aCommandPath.mCommandId), ChipLogValueMEI(aCommandPath.mClusterId));
            return Protocols::InteractionModel::Status::UnsupportedCommand;
        }
        }
    }

    if (CHIP_NO_ERROR != TLVError || !wasHandled)
    {
        ChipLogProgress(Zcl, "Failed to dispatch command, TLVError=%" CHIP_ERROR_FORMAT, TLVError.Format());
        return Protocols::InteractionModel::Status::InvalidCommand;
    }

    // We use success as a marker that no special handling is required
    // This is to avoid having a std::optional which uses slightly more code.
    return Protocols::InteractionModel::Status::Success;
}

} // namespace FanControl

namespace FaultInjection {

Protocols::InteractionModel::Status DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath,
                                                          TLV::TLVReader & aDataTlv)
{
    CHIP_ERROR TLVError = CHIP_NO_ERROR;
    bool wasHandled     = false;
    {
        switch (aCommandPath.mCommandId)
        {
        case Commands::FailAtFault::Id: {
            Commands::FailAtFault::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfFaultInjectionClusterFailAtFaultCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::FailRandomlyAtFault::Id: {
            Commands::FailRandomlyAtFault::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfFaultInjectionClusterFailRandomlyAtFaultCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        default: {
            // Unrecognized command ID, error status will apply.
            ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI,
                         ChipLogValueMEI(aCommandPath.mCommandId), ChipLogValueMEI(aCommandPath.mClusterId));
            return Protocols::InteractionModel::Status::UnsupportedCommand;
        }
        }
    }

    if (CHIP_NO_ERROR != TLVError || !wasHandled)
    {
        ChipLogProgress(Zcl, "Failed to dispatch command, TLVError=%" CHIP_ERROR_FORMAT, TLVError.Format());
        return Protocols::InteractionModel::Status::InvalidCommand;
    }

    // We use success as a marker that no special handling is required
    // This is to avoid having a std::optional which uses slightly more code.
    return Protocols::InteractionModel::Status::Success;
}

} // namespace FaultInjection

namespace Groups {

Protocols::InteractionModel::Status DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath,
                                                          TLV::TLVReader & aDataTlv)
{
    CHIP_ERROR TLVError = CHIP_NO_ERROR;
    bool wasHandled     = false;
    {
        switch (aCommandPath.mCommandId)
        {
        case Commands::AddGroup::Id: {
            Commands::AddGroup::DecodableType commandData;
            TLVError = commandData.Decode(aDataTlv, apCommandObj->GetAccessingFabricIndex());
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfGroupsClusterAddGroupCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::ViewGroup::Id: {
            Commands::ViewGroup::DecodableType commandData;
            TLVError = commandData.Decode(aDataTlv, apCommandObj->GetAccessingFabricIndex());
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfGroupsClusterViewGroupCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::GetGroupMembership::Id: {
            Commands::GetGroupMembership::DecodableType commandData;
            TLVError = commandData.Decode(aDataTlv, apCommandObj->GetAccessingFabricIndex());
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfGroupsClusterGetGroupMembershipCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::RemoveGroup::Id: {
            Commands::RemoveGroup::DecodableType commandData;
            TLVError = commandData.Decode(aDataTlv, apCommandObj->GetAccessingFabricIndex());
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfGroupsClusterRemoveGroupCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::RemoveAllGroups::Id: {
            Commands::RemoveAllGroups::DecodableType commandData;
            TLVError = commandData.Decode(aDataTlv, apCommandObj->GetAccessingFabricIndex());
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfGroupsClusterRemoveAllGroupsCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::AddGroupIfIdentifying::Id: {
            Commands::AddGroupIfIdentifying::DecodableType commandData;
            TLVError = commandData.Decode(aDataTlv, apCommandObj->GetAccessingFabricIndex());
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfGroupsClusterAddGroupIfIdentifyingCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        default: {
            // Unrecognized command ID, error status will apply.
            ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI,
                         ChipLogValueMEI(aCommandPath.mCommandId), ChipLogValueMEI(aCommandPath.mClusterId));
            return Protocols::InteractionModel::Status::UnsupportedCommand;
        }
        }
    }

    if (CHIP_NO_ERROR != TLVError || !wasHandled)
    {
        ChipLogProgress(Zcl, "Failed to dispatch command, TLVError=%" CHIP_ERROR_FORMAT, TLVError.Format());
        return Protocols::InteractionModel::Status::InvalidCommand;
    }

    // We use success as a marker that no special handling is required
    // This is to avoid having a std::optional which uses slightly more code.
    return Protocols::InteractionModel::Status::Success;
}

} // namespace Groups

namespace LevelControl {

Protocols::InteractionModel::Status DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath,
                                                          TLV::TLVReader & aDataTlv)
{
    CHIP_ERROR TLVError = CHIP_NO_ERROR;
    bool wasHandled     = false;
    {
        switch (aCommandPath.mCommandId)
        {
        case Commands::MoveToLevel::Id: {
            Commands::MoveToLevel::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfLevelControlClusterMoveToLevelCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::Move::Id: {
            Commands::Move::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfLevelControlClusterMoveCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::Step::Id: {
            Commands::Step::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfLevelControlClusterStepCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::Stop::Id: {
            Commands::Stop::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfLevelControlClusterStopCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::MoveToLevelWithOnOff::Id: {
            Commands::MoveToLevelWithOnOff::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfLevelControlClusterMoveToLevelWithOnOffCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::MoveWithOnOff::Id: {
            Commands::MoveWithOnOff::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfLevelControlClusterMoveWithOnOffCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::StepWithOnOff::Id: {
            Commands::StepWithOnOff::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfLevelControlClusterStepWithOnOffCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::StopWithOnOff::Id: {
            Commands::StopWithOnOff::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfLevelControlClusterStopWithOnOffCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        default: {
            // Unrecognized command ID, error status will apply.
            ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI,
                         ChipLogValueMEI(aCommandPath.mCommandId), ChipLogValueMEI(aCommandPath.mClusterId));
            return Protocols::InteractionModel::Status::UnsupportedCommand;
        }
        }
    }

    if (CHIP_NO_ERROR != TLVError || !wasHandled)
    {
        ChipLogProgress(Zcl, "Failed to dispatch command, TLVError=%" CHIP_ERROR_FORMAT, TLVError.Format());
        return Protocols::InteractionModel::Status::InvalidCommand;
    }

    // We use success as a marker that no special handling is required
    // This is to avoid having a std::optional which uses slightly more code.
    return Protocols::InteractionModel::Status::Success;
}

} // namespace LevelControl

namespace LowPower {

Protocols::InteractionModel::Status DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath,
                                                          TLV::TLVReader & aDataTlv)
{
    CHIP_ERROR TLVError = CHIP_NO_ERROR;
    bool wasHandled     = false;
    {
        switch (aCommandPath.mCommandId)
        {
        case Commands::Sleep::Id: {
            Commands::Sleep::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfLowPowerClusterSleepCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        default: {
            // Unrecognized command ID, error status will apply.
            ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI,
                         ChipLogValueMEI(aCommandPath.mCommandId), ChipLogValueMEI(aCommandPath.mClusterId));
            return Protocols::InteractionModel::Status::UnsupportedCommand;
        }
        }
    }

    if (CHIP_NO_ERROR != TLVError || !wasHandled)
    {
        ChipLogProgress(Zcl, "Failed to dispatch command, TLVError=%" CHIP_ERROR_FORMAT, TLVError.Format());
        return Protocols::InteractionModel::Status::InvalidCommand;
    }

    // We use success as a marker that no special handling is required
    // This is to avoid having a std::optional which uses slightly more code.
    return Protocols::InteractionModel::Status::Success;
}

} // namespace LowPower

namespace ModeSelect {

Protocols::InteractionModel::Status DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath,
                                                          TLV::TLVReader & aDataTlv)
{
    CHIP_ERROR TLVError = CHIP_NO_ERROR;
    bool wasHandled     = false;
    {
        switch (aCommandPath.mCommandId)
        {
        case Commands::ChangeToMode::Id: {
            Commands::ChangeToMode::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfModeSelectClusterChangeToModeCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        default: {
            // Unrecognized command ID, error status will apply.
            ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI,
                         ChipLogValueMEI(aCommandPath.mCommandId), ChipLogValueMEI(aCommandPath.mClusterId));
            return Protocols::InteractionModel::Status::UnsupportedCommand;
        }
        }
    }

    if (CHIP_NO_ERROR != TLVError || !wasHandled)
    {
        ChipLogProgress(Zcl, "Failed to dispatch command, TLVError=%" CHIP_ERROR_FORMAT, TLVError.Format());
        return Protocols::InteractionModel::Status::InvalidCommand;
    }

    // We use success as a marker that no special handling is required
    // This is to avoid having a std::optional which uses slightly more code.
    return Protocols::InteractionModel::Status::Success;
}

} // namespace ModeSelect

namespace OtaSoftwareUpdateRequestor {

Protocols::InteractionModel::Status DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath,
                                                          TLV::TLVReader & aDataTlv)
{
    CHIP_ERROR TLVError = CHIP_NO_ERROR;
    bool wasHandled     = false;
    {
        switch (aCommandPath.mCommandId)
        {
        case Commands::AnnounceOTAProvider::Id: {
            Commands::AnnounceOTAProvider::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled =
                    emberAfOtaSoftwareUpdateRequestorClusterAnnounceOTAProviderCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        default: {
            // Unrecognized command ID, error status will apply.
            ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI,
                         ChipLogValueMEI(aCommandPath.mCommandId), ChipLogValueMEI(aCommandPath.mClusterId));
            return Protocols::InteractionModel::Status::UnsupportedCommand;
        }
        }
    }

    if (CHIP_NO_ERROR != TLVError || !wasHandled)
    {
        ChipLogProgress(Zcl, "Failed to dispatch command, TLVError=%" CHIP_ERROR_FORMAT, TLVError.Format());
        return Protocols::InteractionModel::Status::InvalidCommand;
    }

    // We use success as a marker that no special handling is required
    // This is to avoid having a std::optional which uses slightly more code.
    return Protocols::InteractionModel::Status::Success;
}

} // namespace OtaSoftwareUpdateRequestor

namespace OnOff {

Protocols::InteractionModel::Status DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath,
                                                          TLV::TLVReader & aDataTlv)
{
    CHIP_ERROR TLVError = CHIP_NO_ERROR;
    bool wasHandled     = false;
    {
        switch (aCommandPath.mCommandId)
        {
        case Commands::Off::Id: {
            Commands::Off::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfOnOffClusterOffCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::On::Id: {
            Commands::On::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfOnOffClusterOnCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::Toggle::Id: {
            Commands::Toggle::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfOnOffClusterToggleCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::OffWithEffect::Id: {
            Commands::OffWithEffect::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfOnOffClusterOffWithEffectCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::OnWithRecallGlobalScene::Id: {
            Commands::OnWithRecallGlobalScene::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfOnOffClusterOnWithRecallGlobalSceneCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::OnWithTimedOff::Id: {
            Commands::OnWithTimedOff::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfOnOffClusterOnWithTimedOffCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        default: {
            // Unrecognized command ID, error status will apply.
            ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI,
                         ChipLogValueMEI(aCommandPath.mCommandId), ChipLogValueMEI(aCommandPath.mClusterId));
            return Protocols::InteractionModel::Status::UnsupportedCommand;
        }
        }
    }

    if (CHIP_NO_ERROR != TLVError || !wasHandled)
    {
        ChipLogProgress(Zcl, "Failed to dispatch command, TLVError=%" CHIP_ERROR_FORMAT, TLVError.Format());
        return Protocols::InteractionModel::Status::InvalidCommand;
    }

    // We use success as a marker that no special handling is required
    // This is to avoid having a std::optional which uses slightly more code.
    return Protocols::InteractionModel::Status::Success;
}

} // namespace OnOff

namespace SmokeCoAlarm {

Protocols::InteractionModel::Status DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath,
                                                          TLV::TLVReader & aDataTlv)
{
    CHIP_ERROR TLVError = CHIP_NO_ERROR;
    bool wasHandled     = false;
    {
        switch (aCommandPath.mCommandId)
        {
        case Commands::SelfTestRequest::Id: {
            Commands::SelfTestRequest::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfSmokeCoAlarmClusterSelfTestRequestCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        default: {
            // Unrecognized command ID, error status will apply.
            ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI,
                         ChipLogValueMEI(aCommandPath.mCommandId), ChipLogValueMEI(aCommandPath.mClusterId));
            return Protocols::InteractionModel::Status::UnsupportedCommand;
        }
        }
    }

    if (CHIP_NO_ERROR != TLVError || !wasHandled)
    {
        ChipLogProgress(Zcl, "Failed to dispatch command, TLVError=%" CHIP_ERROR_FORMAT, TLVError.Format());
        return Protocols::InteractionModel::Status::InvalidCommand;
    }

    // We use success as a marker that no special handling is required
    // This is to avoid having a std::optional which uses slightly more code.
    return Protocols::InteractionModel::Status::Success;
}

} // namespace SmokeCoAlarm

namespace TemperatureControl {

Protocols::InteractionModel::Status DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath,
                                                          TLV::TLVReader & aDataTlv)
{
    CHIP_ERROR TLVError = CHIP_NO_ERROR;
    bool wasHandled     = false;
    {
        switch (aCommandPath.mCommandId)
        {
        case Commands::SetTemperature::Id: {
            Commands::SetTemperature::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfTemperatureControlClusterSetTemperatureCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        default: {
            // Unrecognized command ID, error status will apply.
            ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI,
                         ChipLogValueMEI(aCommandPath.mCommandId), ChipLogValueMEI(aCommandPath.mClusterId));
            return Protocols::InteractionModel::Status::UnsupportedCommand;
        }
        }
    }

    if (CHIP_NO_ERROR != TLVError || !wasHandled)
    {
        ChipLogProgress(Zcl, "Failed to dispatch command, TLVError=%" CHIP_ERROR_FORMAT, TLVError.Format());
        return Protocols::InteractionModel::Status::InvalidCommand;
    }

    // We use success as a marker that no special handling is required
    // This is to avoid having a std::optional which uses slightly more code.
    return Protocols::InteractionModel::Status::Success;
}

} // namespace TemperatureControl

namespace Thermostat {

Protocols::InteractionModel::Status DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath,
                                                          TLV::TLVReader & aDataTlv)
{
    CHIP_ERROR TLVError = CHIP_NO_ERROR;
    bool wasHandled     = false;
    {
        switch (aCommandPath.mCommandId)
        {
        case Commands::SetpointRaiseLower::Id: {
            Commands::SetpointRaiseLower::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfThermostatClusterSetpointRaiseLowerCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::SetActiveScheduleRequest::Id: {
            Commands::SetActiveScheduleRequest::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfThermostatClusterSetActiveScheduleRequestCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::SetActivePresetRequest::Id: {
            Commands::SetActivePresetRequest::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfThermostatClusterSetActivePresetRequestCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::AtomicRequest::Id: {
            Commands::AtomicRequest::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfThermostatClusterAtomicRequestCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        default: {
            // Unrecognized command ID, error status will apply.
            ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI,
                         ChipLogValueMEI(aCommandPath.mCommandId), ChipLogValueMEI(aCommandPath.mClusterId));
            return Protocols::InteractionModel::Status::UnsupportedCommand;
        }
        }
    }

    if (CHIP_NO_ERROR != TLVError || !wasHandled)
    {
        ChipLogProgress(Zcl, "Failed to dispatch command, TLVError=%" CHIP_ERROR_FORMAT, TLVError.Format());
        return Protocols::InteractionModel::Status::InvalidCommand;
    }

    // We use success as a marker that no special handling is required
    // This is to avoid having a std::optional which uses slightly more code.
    return Protocols::InteractionModel::Status::Success;
}

} // namespace Thermostat

namespace ThreadNetworkDiagnostics {

Protocols::InteractionModel::Status DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath,
                                                          TLV::TLVReader & aDataTlv)
{
    CHIP_ERROR TLVError = CHIP_NO_ERROR;
    bool wasHandled     = false;
    {
        switch (aCommandPath.mCommandId)
        {
        case Commands::ResetCounts::Id: {
            Commands::ResetCounts::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfThreadNetworkDiagnosticsClusterResetCountsCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        default: {
            // Unrecognized command ID, error status will apply.
            ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI,
                         ChipLogValueMEI(aCommandPath.mCommandId), ChipLogValueMEI(aCommandPath.mClusterId));
            return Protocols::InteractionModel::Status::UnsupportedCommand;
        }
        }
    }

    if (CHIP_NO_ERROR != TLVError || !wasHandled)
    {
        ChipLogProgress(Zcl, "Failed to dispatch command, TLVError=%" CHIP_ERROR_FORMAT, TLVError.Format());
        return Protocols::InteractionModel::Status::InvalidCommand;
    }

    // We use success as a marker that no special handling is required
    // This is to avoid having a std::optional which uses slightly more code.
    return Protocols::InteractionModel::Status::Success;
}

} // namespace ThreadNetworkDiagnostics

namespace UnitTesting {

Protocols::InteractionModel::Status DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath,
                                                          TLV::TLVReader & aDataTlv)
{
    CHIP_ERROR TLVError = CHIP_NO_ERROR;
    bool wasHandled     = false;
    {
        switch (aCommandPath.mCommandId)
        {
        case Commands::Test::Id: {
            Commands::Test::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfUnitTestingClusterTestCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::TestNotHandled::Id: {
            Commands::TestNotHandled::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfUnitTestingClusterTestNotHandledCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::TestSpecific::Id: {
            Commands::TestSpecific::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfUnitTestingClusterTestSpecificCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::TestAddArguments::Id: {
            Commands::TestAddArguments::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfUnitTestingClusterTestAddArgumentsCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::TestStructArgumentRequest::Id: {
            Commands::TestStructArgumentRequest::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfUnitTestingClusterTestStructArgumentRequestCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::TestNestedStructArgumentRequest::Id: {
            Commands::TestNestedStructArgumentRequest::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled =
                    emberAfUnitTestingClusterTestNestedStructArgumentRequestCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::TestListStructArgumentRequest::Id: {
            Commands::TestListStructArgumentRequest::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled =
                    emberAfUnitTestingClusterTestListStructArgumentRequestCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::TestListInt8UArgumentRequest::Id: {
            Commands::TestListInt8UArgumentRequest::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfUnitTestingClusterTestListInt8UArgumentRequestCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::TestNestedStructListArgumentRequest::Id: {
            Commands::TestNestedStructListArgumentRequest::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled =
                    emberAfUnitTestingClusterTestNestedStructListArgumentRequestCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::TestListNestedStructListArgumentRequest::Id: {
            Commands::TestListNestedStructListArgumentRequest::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfUnitTestingClusterTestListNestedStructListArgumentRequestCallback(apCommandObj, aCommandPath,
                                                                                                      commandData);
            }
            break;
        }
        case Commands::TestListInt8UReverseRequest::Id: {
            Commands::TestListInt8UReverseRequest::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfUnitTestingClusterTestListInt8UReverseRequestCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::TestEnumsRequest::Id: {
            Commands::TestEnumsRequest::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfUnitTestingClusterTestEnumsRequestCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::TestNullableOptionalRequest::Id: {
            Commands::TestNullableOptionalRequest::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfUnitTestingClusterTestNullableOptionalRequestCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::SimpleStructEchoRequest::Id: {
            Commands::SimpleStructEchoRequest::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfUnitTestingClusterSimpleStructEchoRequestCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::TimedInvokeRequest::Id: {
            Commands::TimedInvokeRequest::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfUnitTestingClusterTimedInvokeRequestCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::TestSimpleOptionalArgumentRequest::Id: {
            Commands::TestSimpleOptionalArgumentRequest::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled =
                    emberAfUnitTestingClusterTestSimpleOptionalArgumentRequestCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::TestEmitTestEventRequest::Id: {
            Commands::TestEmitTestEventRequest::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfUnitTestingClusterTestEmitTestEventRequestCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::TestEmitTestFabricScopedEventRequest::Id: {
            Commands::TestEmitTestFabricScopedEventRequest::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled =
                    emberAfUnitTestingClusterTestEmitTestFabricScopedEventRequestCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::TestBatchHelperRequest::Id: {
            Commands::TestBatchHelperRequest::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfUnitTestingClusterTestBatchHelperRequestCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::TestSecondBatchHelperRequest::Id: {
            Commands::TestSecondBatchHelperRequest::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfUnitTestingClusterTestSecondBatchHelperRequestCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::TestDifferentVendorMeiRequest::Id: {
            Commands::TestDifferentVendorMeiRequest::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled =
                    emberAfUnitTestingClusterTestDifferentVendorMeiRequestCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        default: {
            // Unrecognized command ID, error status will apply.
            ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI,
                         ChipLogValueMEI(aCommandPath.mCommandId), ChipLogValueMEI(aCommandPath.mClusterId));
            return Protocols::InteractionModel::Status::UnsupportedCommand;
        }
        }
    }

    if (CHIP_NO_ERROR != TLVError || !wasHandled)
    {
        ChipLogProgress(Zcl, "Failed to dispatch command, TLVError=%" CHIP_ERROR_FORMAT, TLVError.Format());
        return Protocols::InteractionModel::Status::InvalidCommand;
    }

    // We use success as a marker that no special handling is required
    // This is to avoid having a std::optional which uses slightly more code.
    return Protocols::InteractionModel::Status::Success;
}

} // namespace UnitTesting

namespace ValveConfigurationAndControl {

Protocols::InteractionModel::Status DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath,
                                                          TLV::TLVReader & aDataTlv)
{
    CHIP_ERROR TLVError = CHIP_NO_ERROR;
    bool wasHandled     = false;
    {
        switch (aCommandPath.mCommandId)
        {
        case Commands::Open::Id: {
            Commands::Open::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfValveConfigurationAndControlClusterOpenCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::Close::Id: {
            Commands::Close::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfValveConfigurationAndControlClusterCloseCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        default: {
            // Unrecognized command ID, error status will apply.
            ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI,
                         ChipLogValueMEI(aCommandPath.mCommandId), ChipLogValueMEI(aCommandPath.mClusterId));
            return Protocols::InteractionModel::Status::UnsupportedCommand;
        }
        }
    }

    if (CHIP_NO_ERROR != TLVError || !wasHandled)
    {
        ChipLogProgress(Zcl, "Failed to dispatch command, TLVError=%" CHIP_ERROR_FORMAT, TLVError.Format());
        return Protocols::InteractionModel::Status::InvalidCommand;
    }

    // We use success as a marker that no special handling is required
    // This is to avoid having a std::optional which uses slightly more code.
    return Protocols::InteractionModel::Status::Success;
}

} // namespace ValveConfigurationAndControl

namespace WindowCovering {

Protocols::InteractionModel::Status DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath,
                                                          TLV::TLVReader & aDataTlv)
{
    CHIP_ERROR TLVError = CHIP_NO_ERROR;
    bool wasHandled     = false;
    {
        switch (aCommandPath.mCommandId)
        {
        case Commands::UpOrOpen::Id: {
            Commands::UpOrOpen::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfWindowCoveringClusterUpOrOpenCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::DownOrClose::Id: {
            Commands::DownOrClose::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfWindowCoveringClusterDownOrCloseCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::StopMotion::Id: {
            Commands::StopMotion::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfWindowCoveringClusterStopMotionCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::GoToLiftValue::Id: {
            Commands::GoToLiftValue::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfWindowCoveringClusterGoToLiftValueCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::GoToLiftPercentage::Id: {
            Commands::GoToLiftPercentage::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfWindowCoveringClusterGoToLiftPercentageCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::GoToTiltValue::Id: {
            Commands::GoToTiltValue::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfWindowCoveringClusterGoToTiltValueCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        case Commands::GoToTiltPercentage::Id: {
            Commands::GoToTiltPercentage::DecodableType commandData;
            TLVError = DataModel::Decode(aDataTlv, commandData);
            if (TLVError == CHIP_NO_ERROR)
            {
                wasHandled = emberAfWindowCoveringClusterGoToTiltPercentageCallback(apCommandObj, aCommandPath, commandData);
            }
            break;
        }
        default: {
            // Unrecognized command ID, error status will apply.
            ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI,
                         ChipLogValueMEI(aCommandPath.mCommandId), ChipLogValueMEI(aCommandPath.mClusterId));
            return Protocols::InteractionModel::Status::UnsupportedCommand;
        }
        }
    }

    if (CHIP_NO_ERROR != TLVError || !wasHandled)
    {
        ChipLogProgress(Zcl, "Failed to dispatch command, TLVError=%" CHIP_ERROR_FORMAT, TLVError.Format());
        return Protocols::InteractionModel::Status::InvalidCommand;
    }

    // We use success as a marker that no special handling is required
    // This is to avoid having a std::optional which uses slightly more code.
    return Protocols::InteractionModel::Status::Success;
}

} // namespace WindowCovering

} // namespace Clusters

void DispatchSingleClusterCommand(const ConcreteCommandPath & aCommandPath, TLV::TLVReader & aReader, CommandHandler * apCommandObj)
{
    Protocols::InteractionModel::Status errorStatus = Protocols::InteractionModel::Status::Success;

    switch (aCommandPath.mClusterId)
    {
    case Clusters::ColorControl::Id:
        errorStatus = Clusters::ColorControl::DispatchServerCommand(apCommandObj, aCommandPath, aReader);
        break;
    case Clusters::DishwasherAlarm::Id:
        errorStatus = Clusters::DishwasherAlarm::DispatchServerCommand(apCommandObj, aCommandPath, aReader);
        break;
    case Clusters::FanControl::Id:
        errorStatus = Clusters::FanControl::DispatchServerCommand(apCommandObj, aCommandPath, aReader);
        break;
    case Clusters::FaultInjection::Id:
        errorStatus = Clusters::FaultInjection::DispatchServerCommand(apCommandObj, aCommandPath, aReader);
        break;
    case Clusters::Groups::Id:
        errorStatus = Clusters::Groups::DispatchServerCommand(apCommandObj, aCommandPath, aReader);
        break;
    case Clusters::LevelControl::Id:
        errorStatus = Clusters::LevelControl::DispatchServerCommand(apCommandObj, aCommandPath, aReader);
        break;
    case Clusters::LowPower::Id:
        errorStatus = Clusters::LowPower::DispatchServerCommand(apCommandObj, aCommandPath, aReader);
        break;
    case Clusters::ModeSelect::Id:
        errorStatus = Clusters::ModeSelect::DispatchServerCommand(apCommandObj, aCommandPath, aReader);
        break;
    case Clusters::OtaSoftwareUpdateRequestor::Id:
        errorStatus = Clusters::OtaSoftwareUpdateRequestor::DispatchServerCommand(apCommandObj, aCommandPath, aReader);
        break;
    case Clusters::OnOff::Id:
        errorStatus = Clusters::OnOff::DispatchServerCommand(apCommandObj, aCommandPath, aReader);
        break;
    case Clusters::SmokeCoAlarm::Id:
        errorStatus = Clusters::SmokeCoAlarm::DispatchServerCommand(apCommandObj, aCommandPath, aReader);
        break;
    case Clusters::TemperatureControl::Id:
        errorStatus = Clusters::TemperatureControl::DispatchServerCommand(apCommandObj, aCommandPath, aReader);
        break;
    case Clusters::Thermostat::Id:
        errorStatus = Clusters::Thermostat::DispatchServerCommand(apCommandObj, aCommandPath, aReader);
        break;
    case Clusters::ThreadNetworkDiagnostics::Id:
        errorStatus = Clusters::ThreadNetworkDiagnostics::DispatchServerCommand(apCommandObj, aCommandPath, aReader);
        break;
    case Clusters::UnitTesting::Id:
        errorStatus = Clusters::UnitTesting::DispatchServerCommand(apCommandObj, aCommandPath, aReader);
        break;
    case Clusters::ValveConfigurationAndControl::Id:
        errorStatus = Clusters::ValveConfigurationAndControl::DispatchServerCommand(apCommandObj, aCommandPath, aReader);
        break;
    case Clusters::WindowCovering::Id:
        errorStatus = Clusters::WindowCovering::DispatchServerCommand(apCommandObj, aCommandPath, aReader);
        break;
    default:
        ChipLogError(Zcl, "Unknown cluster " ChipLogFormatMEI, ChipLogValueMEI(aCommandPath.mClusterId));
        errorStatus = Protocols::InteractionModel::Status::UnsupportedCluster;
        break;
    }

    if (errorStatus != Protocols::InteractionModel::Status::Success)
    {
        apCommandObj->AddStatus(aCommandPath, errorStatus);
    }
}

} // namespace app
} // namespace chip
